/*
 *
 * Copyright (C) 2012 Walter Lütgenau
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 */
package offset.nodes.client.virtual.model.jcr;

import java.io.InputStream;
import javax.jcr.Node;
import javax.xml.parsers.SAXParserFactory;
import offset.nodes.Constants;
import offset.nodes.client.model.DummyContentHandler;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

/**
 *
 * @author Walter Lütgenau
 */
public class NodeReader extends DummyContentHandler implements ContentHandler {

    Node node = null;
    Node root = null;
    NodePerTypeFactory factory;

    public NodeReader(NodePerTypeFactory factory) {
        this.factory = factory;
    }

    public NodeReader(Node root) {
        this.root = this.node = root;
    }
    
    public NodeReader() {
        this(new NodePerTypeFactory() {

            public Node newNode(String nodeType) {
                SimpleNode result = new SimpleNode("");
                result.setNodeType(nodeType);
                
                return result;
            }
            
        });
    }

    public Node read(InputStream in) throws Exception {
        XMLReader reader = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
        reader.setContentHandler(this);

        reader.parse(new InputSource(in));

        return root;
    }

    public void endElement(String uri, String localName, String qName) throws SAXException {
        try {
            if (node.getParent() != null) {
                node = node.getParent();
            }
        } catch (Exception e) {
            throw new SAXException(e);
        }
    }

    public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
        try {
            String name = XmlNameConverter.decodeName(qName);
            String nodeType = atts.getValue(Constants.JCR_PRIMARY_TYPE);
            if (node == null) {
                root = node = factory.newNode(nodeType);
                if ( node instanceof SimpleNode) {
                    ((SimpleNode)node).setName(name);
                }
            } else {
                if ( node instanceof SimpleNode )
                    ((SimpleNode)node).setNodePerTypeFactory(factory);
                node = node.addNode(name, nodeType);
            }

            for (int i = 0; i < atts.getLength(); i++) {
                if (!atts.getQName(i).equals(Constants.JCR_PRIMARY_TYPE))
                    node.setProperty(XmlNameConverter.decodeName(atts.getQName(i)), atts.getValue(i));
            }
        } catch (Exception e) {
            throw new SAXException(e);
        }
    }
}

